/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package am.aua.renju.web;

import am.aua.renju.bussinesslayer.GameManager;
import am.aua.renju.bussinesslayer.MoveData;
import am.aua.renju.bussinesslayer.NewGameInfo;
import am.aua.renju.bussinesslayer.UserManager;
import am.aua.renju.bussinesslayer.exception.EmailAlreadyRegistredException;
import am.aua.renju.bussinesslayer.exception.GameDuplicationException;
import am.aua.renju.bussinesslayer.exception.InvalidInputException;
import am.aua.renju.bussinesslayer.exception.NicknameAlreadyRegistredException;
import am.aua.renju.bussinesslayer.gamelogic.GameLogic.GameLogicState;
import am.aua.renju.entity.Player;
import am.aua.renju.web.filldata.CreateGame;
import am.aua.renju.web.filldata.HeaderContain;
import am.aua.renju.web.filldata.Index;
import am.aua.renju.web.filldata.JoinGame;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 *
 * @author Ara Yeritsian
 */
public class Controller {

    private TemplateRender templateRender;
    private UserManager userManager;
    private GameManager gm;

    public Controller(ServletContext servletContext) {
        templateRender = new TemplateRender(servletContext, "templates/pc");
        userManager = UserManager.getInstance();
        gm = GameManager.getInstance();
    }
    
    private boolean sessionAuthenticate(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        String email = (String) session.getAttribute("email");
        String password = (String) session.getAttribute("password");
        if (email == null || password == null) {
            return false;
        }
        return userManager.autenticate(email, password);
    }

    public void loggedin(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        if (email != null && password != null && userManager.autenticate(email, password)) {
            session.setAttribute("email", email);
            session.setAttribute("password", password);          
            String nickname=userManager.getNickname(email);
            session.setAttribute("nickname", nickname);
            templateRender.render(response, Index.load(HeaderContain.loadLoggedIn(nickname)));
        } else {
            templateRender.render(response, Index.load(HeaderContain.loadLoginError()));
        }
    }

    public void registered(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        String nickname = request.getParameter("nickname");
        String securityQuestion = request.getParameter("securityQuestion");
        String answer = request.getParameter("securityQuestionAnswer");
        try {
            userManager.register(email, password, nickname, securityQuestion, answer);
            templateRender.ajaxRender(response, HeaderContain.loadRegistrationSuccessfull(nickname));
        } catch (EmailAlreadyRegistredException ex) {
            templateRender.ajaxRender(response, HeaderContain.loadErrorRegistrationEmail());
        } catch (NicknameAlreadyRegistredException ex) {
            templateRender.ajaxRender(response, HeaderContain.loadErrorRegistrationNickName());            
        } catch (InvalidInputException ex) {
            templateRender.render(response, Index.load(HeaderContain.load()));
        }        
    }
    
    public void logout(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        String email=(String)session.getAttribute("email");
        gm.clearCreatedGames(email);
        session.removeAttribute("email");
        session.removeAttribute("password");
        templateRender.render(response, Index.load(HeaderContain.load()));
    }

    public void sessionDriven(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {            
            String nickname = (String) request.getSession(false).getAttribute("nickname"); 
            templateRender.render(response, Index.load(HeaderContain.loadLoggedIn(nickname))); 
        } else {
            templateRender.render(response, Index.load(HeaderContain.load()));
        }
    }

    public void createGame(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {
            templateRender.render(response, CreateGame.load());
        } else {
            templateRender.render(response, Index.load(HeaderContain.load()));
        }
    }

    public void createdGame(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {
            boolean startRule = request.getParameter("startRule") != null;
            String email = request.getSession().getAttribute("email").toString();
            String nickname = (String) request.getSession(false).getAttribute("nickname"); 
            if (request.getParameter("time").equals("")) {
                try {
                    if (gm.createGame(email, startRule)) {
                        templateRender.render(response, Index.loadErrorCreateGameLimit(HeaderContain.loadLoggedIn(nickname)));
                    }
                } catch (GameDuplicationException ex) {
                    templateRender.render(response, Index.loadErrorGameDuplication(HeaderContain.loadLoggedIn(nickname)));
                    return;
                }
            } else {
                int time = Integer.parseInt(request.getParameter("time"));                
                try {
                    if (gm.createGame(email, startRule, time)) {
                        templateRender.render(response, Index.loadErrorCreateGameLimit(HeaderContain.loadLoggedIn(nickname)));
                    }
                } catch (GameDuplicationException ex) {
                    templateRender.render(response, Index.loadErrorGameDuplication(HeaderContain.loadLoggedIn(nickname)));
                    return;
                }
            }
            templateRender.ajaxRender(response, Index.loadAjaxCreateGame());//todo:nickname
        } else {
            templateRender.render(response, Index.load(HeaderContain.load()));
        }
    }

    public void loggedinGameData(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {
            String email=(String) request.getSession(false).getAttribute("email");
            templateRender.ajaxRender(response, Index.loadAjaxGameData(email));
        }
    }

    public void joinGame(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {
            String fromNickname = request.getParameter("from");
            String time = request.getParameter("time");
            String startRule = request.getParameter("startRule");
            String email = request.getSession(false).getAttribute("email").toString();
            NewGameInfo newGameInfo;
            try {
                newGameInfo = gm.joinGame(fromNickname, Integer.parseInt(time.trim()),
                        startRule.equals("true"), email);
            } catch (InvalidInputException ex) {                
                templateRender.render(response, Index.load(HeaderContain.load()));
                return;
            }
            String nickname = (String) request.getSession(false).getAttribute("nickname"); 
            templateRender.render(response, JoinGame.load(newGameInfo, HeaderContain.loadLoggedIn(nickname)));
        }
    }
    
    public void deleteGame(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        if (sessionAuthenticate(request)) {            
            String time = request.getParameter("time");
            String startRule = request.getParameter("startRule");
            String email = request.getSession(false).getAttribute("email").toString();
            gm.deleteGame(email,Integer.parseInt(time),startRule.equals("true"));
            String nickname = (String) request.getSession(false).getAttribute("nickname"); 
            templateRender.render(response, Index.load(HeaderContain.loadLoggedIn(nickname)));
        }
    }

    public void joinGameHost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if (sessionAuthenticate(request)) {
            String email = request.getSession(false).getAttribute("email").toString();
            NewGameInfo joinGameReturn = gm.joinGameHost(email);
            String nickname = (String) request.getSession(false).getAttribute("nickname"); 
            templateRender.render(response, JoinGame.load(joinGameReturn, HeaderContain.loadLoggedIn(nickname)));
        }
    }

    public void joinRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (sessionAuthenticate(request)) {
            String email = request.getSession(false).getAttribute("email").toString();
            gm.joinGame(email);
            if (gm.joinRequest(email)) {
                templateRender.ajaxRender(response, JoinGame.loadAjaxJoinRequest(true));
            } else {
                templateRender.ajaxRender(response, JoinGame.loadAjaxJoinRequest(false));
            }
        }
    }

    public void play(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (sessionAuthenticate(request)) {
            int x = Integer.parseInt(request.getParameter("x"));
            int y = Integer.parseInt(request.getParameter("y"));
            String email = (String) request.getSession(false).getAttribute("email");
            GameLogicState gameLogicState = gm.play(email, x, y);
            templateRender.ajaxRender(response, JoinGame.loadAjaxPlay(gameLogicState));
        }
    }

    public void opponentPlay(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if(sessionAuthenticate(request)){
            String email = (String) request.getSession(false).getAttribute("email");
            MoveData opponentPlayReturn = gm.opponentPlay(email);
            templateRender.ajaxRender(response, JoinGame.loadAjaxOpponentPlay(opponentPlayReturn));
        }
    }
    
    public void isMyTurn(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if(sessionAuthenticate(request)){
            String email = (String) request.getSession(false).getAttribute("email");
            boolean isMyTurn=!gm.playerIsWhite(email);
            templateRender.ajaxRender(response,JoinGame.loadAjaxIsMyTurn(isMyTurn));
        }
    }

    public void top10Players(HttpServletRequest request, HttpServletResponse response) throws IOException {
        List<Player> top10Players=userManager.getTop10Players();
        templateRender.ajaxRender(response,Index.loadAjaxTop10Players(top10Players));
    }
}
